package com.bacon.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bacon.gmall.common.util.HttpClientUtil;
import com.bacon.gmall.common.utils.RabbitUtil;
import com.bacon.gmall.model.enums.OrderStatus;
import com.bacon.gmall.model.enums.PaymentWay;
import com.bacon.gmall.model.enums.ProcessStatus;
import com.bacon.gmall.model.order.OrderDetail;
import com.bacon.gmall.model.order.OrderInfo;
import com.bacon.gmall.order.mapper.CartMapper;
import com.bacon.gmall.order.mapper.OrderDetailMapper;
import com.bacon.gmall.order.mapper.OrderMapper;
import com.bacon.gmall.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author： bacon、
 * @version： 1.0
 * @create： 2021-01-06 19:57
 * @description:
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitUtil rabbitUtil;

    @Value("${ware.url}")
    private String WareUrl;

    //判断是否有货
    @Override
    public Boolean hasStock(Long skuId, Integer skuNum) {
        String s = HttpClientUtil.doGet(WareUrl + "/hasStock?skuId=" + skuId + "&num=" + skuNum);
        return "1".equals(s);
    }

    //提交订单
    @Override
    @Transactional
    public Long submitOrder(OrderInfo orderInfo) {
        //保存订单表
        //计算总金额
        orderInfo.sumTotalAmount();
        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //订单创建时间
        orderInfo.setCreateTime(new Date());
        //失效时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.HOUR, 2);
        orderInfo.setExpireTime(instance.getTime());
        //进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        //订单编号
        String tradeNo = "userId:" + orderInfo.getUserId() + ":Bacon:" + System.currentTimeMillis() + ":order" + new Random().nextInt(500);
        orderInfo.setOutTradeNo(tradeNo);

        //商品描述
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        ArrayList<String> skuIdStringList = new ArrayList<>();

        StringBuilder sb = new StringBuilder();
        for (OrderDetail orderDetail : orderDetailList) {
            sb.append(orderDetail.getSkuName() + " ");

            //保存订单详情表
            skuIdStringList.add(orderDetail.getSkuId() + "");
        }
        if (sb.length() > 100) {
            orderInfo.setTradeBody(sb.substring(0, 100));
        } else {
            orderInfo.setTradeBody(sb.toString());
        }
        orderInfo.setTotalAmount(new BigDecimal(0.01));
        orderMapper.insert(orderInfo);

        //保存订单详情表
        Long orderId = orderInfo.getId();
        for (OrderDetail orderDetail : orderDetailList) {
            orderDetail.setOrderId(orderId);
            orderDetailMapper.insert(orderDetail);
        }

/*        //删除购物车数据库
        cartMapper.delete(new QueryWrapper<CartInfo>().
                eq("user_id", orderInfo.getUserId()).
                in("sku_id", skuIdStringList.toArray()));

        //删除缓存
        redisTemplate.opsForHash().delete(RedisConst.USER_KEY_PREFIX + orderInfo.getUserId() + RedisConst.USER_CART_KEY_SUFFIX,
                skuIdStringList.toArray());*/

        /*rabbitUtil.sendDeadLetterMessage(
                OrderDeadLetterMQConfig.EXCHANGE_DIRECT_ORDER_CANCEL,
                OrderDeadLetterMQConfig.ROUTING_ORDER_CANCEL1,
                orderInfo.getId(),
                10);*/
        return orderId;
    }

    @Override
    public void orderCancel(Long orderId) {

        //冪等性問題
        //1、不能重复提交
        //2、不能修改已支付订单状态
        //一、查询订单状态
        //二、如果订单为未支付
        //三、如果订单是未支付，改为已关闭，其他状态则不做答
        OrderInfo orderInfo = orderMapper.selectById(orderId);
        if (OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())) {
            orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            orderMapper.updateById(orderInfo);
        }
    }

    @Override
    public OrderInfo getOrderById(Long orderId) {
        return orderMapper.selectById(orderId);
    }

    @Override
    public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
        //订单详情表   skuId 1  skuId 5   同一张订单里
        //1:订单主表 原订单是不变了  原订单父订单 产生2张子订单   保存2条新的订单主表
        //2:订单详情表  修改订单主表的外键
        //[{"wareId":"1","skuIds":["5","6"]},{"wareId":"2","skuIds":["1"]}]
        List<Map> wareSkuMapList = JSONObject.parseArray(wareSkuMap, Map.class);
        OrderInfo originOrderInfo = orderInfoWithDetails(orderId);
        List<OrderDetail> originOrderDetailList = originOrderInfo.getOrderDetailList();

        List<OrderInfo> subOrderInfoList = new ArrayList<>();
        for (Map map : wareSkuMapList) {

            OrderInfo subOrderInfo = new OrderInfo();
            BeanUtils.copyProperties(originOrderInfo,subOrderInfo);
            subOrderInfo.setWareId((String) map.get("wareId"));
            subOrderInfo.setParentOrderId(originOrderInfo.getId());
            subOrderInfo.setId(null);

            List<OrderDetail> orderDetailList = new ArrayList<>();
            for (OrderDetail orderDetail : originOrderDetailList) {
                List<String> skuIds = (List<String>) map.get("skuIds");
                for (String skuId : skuIds) {
                    if (skuId.equals(orderDetail.getSkuId())){
                        orderDetailList.add(orderDetail);
                    }
                }
            }
            //计算该订单每个仓库所含的金额
            subOrderInfo.setOrderDetailList(orderDetailList);
            subOrderInfo.sumTotalAmount();

            //保存子表
            orderMapper.insert(subOrderInfo);

            //批量处理，更改OrderDetail中同一个仓库的订单
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(subOrderInfo.getId());
            List<Long> orderDetails = orderDetailList.stream().map(OrderDetail::getId).collect(Collectors.toList());
            orderDetailMapper.update(orderDetail,new QueryWrapper<OrderDetail>().
                    in("id",orderDetails));

            subOrderInfoList.add(subOrderInfo);
        }
        return subOrderInfoList;
    }

    @Override
    public Map initWareOrder(Long orderId) {
        //准备数据，添加到仓库数据库中
        Map<String, Object> map = new HashMap<>();
        OrderInfo orderInfo = orderInfoWithDetails(orderId);
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();

        //仓库订单表
        map.put("order_id", orderId);
        map.put("consignee", orderInfo.getConsignee());
        map.put("consigneeTel", orderInfo.getConsigneeTel());
        map.put("deliveryAddress", orderInfo.getDeliveryAddress()); //订单地址
        map.put("orderComment", orderInfo.getOrderComment()); //订单备注
        map.put("paymentWay", orderInfo.getPaymentWay().equals(PaymentWay.OUTLINE.name()) ? "2" : "1");
        map.put("orderBody", orderInfo.getTradeBody());

        //在拆单的时候装入，现在使用
        map.put("wareId",orderInfo.getWareId());
        //仓库详情表
        ArrayList<Map> mapArrayList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            Map<String, Object> orderDetailMap = new HashMap<>();
            map.put("sku_id", orderDetail.getSkuId());
            map.put("sku_name", orderDetail.getSkuName());
            map.put("sku_num", orderDetail.getSkuNum());
            mapArrayList.add(orderDetailMap);
        }

        map.put("details", mapArrayList);
        return map;

    }

    public OrderInfo orderInfoWithDetails(Long orderId) {
        //准备数据，添加到仓库数据库中
        OrderInfo orderInfo = orderMapper.selectById(orderId);
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new QueryWrapper<OrderDetail>().
                eq("order_id", orderId));
        orderInfo.setOrderDetailList(orderDetailList);
        return orderInfo;
    }

}
